package dimension.starry.constants;

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtCompound;

import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;

public enum PlayerDataType {

    WATER(
        "water", () -> 10000, (nbtCompound, value) -> nbtCompound.putInt("water", (int) value),
        nbtCompound -> nbtCompound.getInt("water")
    ),
    MAGIC(
        "magic", () -> 1000, (nbtCompound, value) -> nbtCompound.putLong("magic", castToLong(value)),
        nbtCompound -> nbtCompound.getLong("magic")
    ),
    MAX_MAGIC(
        "maxMagic", () -> 1000, (nbtCompound, value) -> nbtCompound.putLong("maxMagic", castToLong(value)),
        nbtCompound -> nbtCompound.getLong("maxMagic")
    ),
    EXP(
        "exp", () -> 0, (nbtCompound, value) -> nbtCompound.putLong("exp", castToLong(value)),
        nbtCompound -> nbtCompound.getLong("exp")
    ),
    LEVEL(
        "level", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("level", (int) value),
        nbtCompound -> nbtCompound.getInt("level")
    ),
    STRENGTH(
        "strength", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("strength", (int) value),
        nbtCompound -> nbtCompound.getInt("strength")
    ),
    STRONG(
        "strong", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("strong", (int) value),
        nbtCompound -> nbtCompound.getInt("strong")
    ),
    AGILE(
        "agile", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("agile", (int) value),
        nbtCompound -> nbtCompound.getInt("agile")
    ),
    WISDOM(
        "wisdom", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("wisdom", (int) value),
        nbtCompound -> nbtCompound.getInt("wisdom")
    ),
    ANALYSIS(
        "analysis", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("analysis", (int) value),
        nbtCompound -> nbtCompound.getInt("analysis")
    ),
    FLEXIBLE(
        "flexible", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("flexible", (int) value),
        nbtCompound -> nbtCompound.getInt("flexible")
    ),
    STAMNA(
        "stamina", () -> 0, (nbtCompound, value) -> nbtCompound.putInt("stamina", (int) value),
        nbtCompound -> nbtCompound.getInt("stamina")
    ),
    ATTRBUTE_POINTS(
        "attrbutePoints", () -> 0, ((nbtCompound, value) -> nbtCompound.putInt("attrbutePoints", (int) value)),
        nbtCompound -> nbtCompound.getInt("attrbutePoints")
    ),
    SKILL_SLOT1(
        "skillSlot1", () -> ItemStack.EMPTY,
        ((nbtCompound, value) -> nbtCompound.put("skillSlot1", ((ItemStack) value).writeNbt(new NbtCompound()))),
        nbtCompound -> nbtCompound.get("skillSlot1")
    ),
    SKILL_SLOT2(
        "skillSlot2", () -> ItemStack.EMPTY,
        ((nbtCompound, value) -> nbtCompound.put("skillSlot2", ((ItemStack) value).writeNbt(new NbtCompound()))),
        nbtCompound -> nbtCompound.get("skillSlot2")
    ),
    SKILL_SLOT3(
        "skillSlot3", () -> ItemStack.EMPTY,
        ((nbtCompound, value) -> nbtCompound.put("skillSlot3", ((ItemStack) value).writeNbt(new NbtCompound()))),
        nbtCompound -> nbtCompound.get("skillSlot3")
    );

    public final Supplier getDefaultValue;
    public final BiConsumer<NbtCompound, Object> putToNbt;
    public final Function<NbtCompound, Object> getFromNbt;
    private final String name;

    PlayerDataType(
        String name, Supplier getDefaultValue, BiConsumer<NbtCompound, Object> putToNbt,
        Function<NbtCompound, Object> getFromNbt
    ) {
        this.name = name;
        this.getDefaultValue = getDefaultValue;
        this.putToNbt = putToNbt;
        this.getFromNbt = getFromNbt;
    }

    private static Long castToLong(Object value) {
        return Long.parseLong(String.valueOf(value));
    }

    public String getName() {
        return name;
    }

}
